import { Injectable } from '@angular/core'
import { HttpClient } from '@angular/common/http'
import { throwError, Observable, of } from 'rxjs'
import { catchError, map } from 'rxjs/operators'

import { MerchantService } from './merchant.service'
import { IMerchantQueryParams, IMerchantPagination, Merchant, ICreateMerchant } from '@shared/interfaces/merchant'
import { COMB_URL } from 'app/utils/contraints'
import { preProcessParams, encodeParams } from '@shared/decorators'
import { IResponse } from '@shared/interfaces/response'

@Injectable()
export class MerchantAlinterService implements MerchantService {

  constructor(
    private http: HttpClient,
  ) {}

  @preProcessParams()
  @encodeParams()
  getList(params: IMerchantQueryParams, str?: string): Observable<IMerchantPagination> {
    const url = `${COMB_URL}/camel/merchants?${str}`
    return this.http.get<IMerchantPagination>(url, {
        withCredentials: true,
      })
      .pipe(
        catchError(err => {
          return throwError(err)
        })
      )
  }

  getOne(intMerCode: string): Observable<Merchant> {
    const url = `${COMB_URL}/camel/merchant/${intMerCode}`
    return this.http.get<Merchant>(url).pipe(
      catchError(err => {
        return of({} as Merchant)
      }),
    )
  }

  create(merchant: ICreateMerchant): Observable<ICreateMerchant> {
    const url = `${COMB_URL}/camel/merchant`
    return this.http.post<ICreateMerchant>(url, merchant).pipe(
      catchError(err => {
        return of({} as ICreateMerchant)
      })
    )
  }

  update(intMerCode: string, merchant: Merchant): Observable<Merchant> {
    const url = `${COMB_URL}/camel/merchant/${intMerCode}`
    return this.http.put<Merchant>(url, merchant).pipe(
      catchError(err => {
        return of({} as Merchant)
      })
    )
  }

  updateAuthPassword(intMerCode: string, authPassword: string): Observable<boolean> {
    const url = `${COMB_URL}/camel/merchant/${intMerCode}/authPassword`
    return this.http.put<boolean>(url, { authPassword })
  }

  delete(intMerCode: string): Observable<boolean> {
    const url = `${COMB_URL}/camel/merchant/${intMerCode}`
    return this.http
      .delete<IResponse>(url, {
        withCredentials: true,
      })
      .pipe(
        map(res => {
          if (res.status !== 0) {
            throw new Error(res.message)
          }
          return true
        }),
        catchError(err => {
          return of(false)
        }),
      )
  }

  /** 冻结 */
  freeze(intMerCode: string): Observable<boolean> {
    const url = `${COMB_URL}/camel/merchant/${intMerCode}/freeze`
    return this.http.put<boolean>(url, {})
  }

  /** 解冻 */
  unfreeze(intMerCode: string): Observable<boolean> {
    const url = `${COMB_URL}/camel/merchant/${intMerCode}/unfreeze`
    return this.http.put<boolean>(url, {})
  }
}
